package cn.lwq.help;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.List;

import cn.lwq.mysql.MysqlConnection;
import cn.lwq.oracle.OracleConnection;

/**
 * @auther lwq 719812998@qq.com
 * @date 2017年7月17日
 * @comment
 */
public abstract class Make {

	private Connection connection;
	
	public Connection getConnection() {
		return connection;
	}

	public void setConnection(Connection connection) {
		this.connection = connection;
	}

	/**
	 * 生成 java Filed
	 */
	public abstract StringBuilder makeJavaField() throws Exception;

	/**
	 * 生成 Sql Filed
	 */
	public abstract StringBuilder makeSqlField() throws Exception;

	/**
	 * 生成 Mybatis Set语句
	 */
	public abstract StringBuilder makeMybatisSet() throws Exception;

	/**
	 * 生成 Mybatis 插入语句
	 */
	public abstract StringBuilder makeMybatisInsert() throws Exception;

	/**
	 * 生成 Mybatis 修改语句
	 */
	public abstract StringBuilder makeMybatisUpdate() throws Exception;

	public void close(PreparedStatement ps, ResultSet rs) throws Exception{
		if(rs != null) rs.close();
		if (ps != null) ps.close();
	}
	
	/**
	 * 转驼峰（条件：下划线）
	 */
	public String turnHump(String str) {
		String $key = "_";
		if(str.indexOf($key) == -1) {
			char s, j=0;
			for(int i=0;i<str.length();i++) {
				s = str.charAt(i);
				if(Character.isUpperCase(s)) j++;
			}
			if(j == str.length()) return str.toLowerCase();
			return str.substring(0,1).toLowerCase() + str.substring(1);
		}
		String[] strs = str.split($key);
		StringBuilder sbStr = new StringBuilder();
		for(int i = 0; i< strs.length; i++) {
			if(i != 0) {
				sbStr.append(strs[i].substring(0,1).toUpperCase() + strs[i].substring(1).toLowerCase());
			} else {
				sbStr.append(strs[i].toLowerCase());
			}
		}
		return sbStr.toString();
	}
	
	private boolean checkNumberLength(String strings){
		return strings != null && Long.parseLong(strings) != 0;
	}
	
	private String getLengthInt(String num) {
		int i = Integer.parseInt(num);
		String tmp = "";
		if(i > 9) {
//			i = i-1;
			i=9;
		}
		for(int j = 0;j<i;j++) {
			tmp += 9;
		}
		return tmp;
	}
	
	private String jian(String a, String b) {
		return String.valueOf(Integer.parseInt(a) - Integer.parseInt(b));
	}
	
	/**
	 * @param objects 
	 * 0. column_name
	 * 1. column_comment
	 * 2. column_type
	 * 3. column_length
	 * 4. 精度 （只有 Oracle 有此判断）
	 * 5. 真实长度 （只有 Oracle 有此判断）
	 */
	public StringBuilder javaFieldCheck(String...strings) {
		StringBuilder sbStr = new StringBuilder();
		String fieldType = "String";
		String string0 = strings[0];
		String string3 = strings[3];
		if(ConfigRead.HUMP) {
			strings[0] = turnHump(strings[0]);
		}
		if(ConfigRead.NOW_DB.equals(ConfigRead.ORACLE)) {
			if(ConfigRead.ANN_NOTNULL) {
				List<String> list = OracleConnection.MAP_COLUMN_TYPE.get(ConfigRead.$NOT_NULL);
				if(list.contains(strings[2])) {
//					sbStr.append("@" + ConfigRead.NOT_NULL_VALUE + "(message=\"参数[" + strings[0] + "]不能为空\")");
					sbStr.append("@");
					sbStr.append(ConfigRead.NOT_NULL_VALUE);
					if(ConfigRead.MESSAGE_NOTNULL) {
						sbStr.append("(message=\""+ String.format(ConfigRead.MESSAGE_NOTNULL_VALUE, strings[0]) +"\")");
					}
					sbStr.append(ConfigRead.NL);
				}
			}
			if(ConfigRead.ANN_LENGTH) {
				List<String> maxs = OracleConnection.MAP_COLUMN_TYPE.get(ConfigRead.$MAX);
				if(maxs.contains(strings[2])) {
					sbStr.append("@Max("+getLengthInt(strings[5]==null?strings[3]:jian(strings[5], strings[4]))+")");
					sbStr.append(ConfigRead.NL);
				}
				List<String> lengths = OracleConnection.MAP_COLUMN_TYPE.get(ConfigRead.$LENGTH);
				if(lengths.contains(strings[2])){
					if(ConfigRead.ANN_LENGTH_2 && checkNumberLength(strings[3])) {
						strings[3] = String.valueOf(Long.parseLong(strings[3]) / 2);
					}
//					sbStr.append("@Length(message=\"参数["+strings[0]+"]长度不能超过"+strings[3]+"\", max = "+strings[3]+")");
					sbStr.append("@Length");
					if(ConfigRead.MESSAGE_LENGTH) {
						sbStr.append("(message=\""+ String.format(ConfigRead.MESSAGE_LENGTH_VALUE, strings[0], strings[3]) +"\", max = "+strings[3]+")");
					} else {
						sbStr.append("(max = "+strings[3]+")");
					}
					sbStr.append(ConfigRead.NL);
				}
			}
			if(ConfigRead.ANN_DATE) {
				List<String> list = OracleConnection.MAP_COLUMN_TYPE.get(ConfigRead.$DATE);
				if(list.contains(strings[2])) {
					sbStr.append("@DateTimeFormat(pattern = \""+ConfigRead.ANN_DATE_FORMAT+"\")");
					sbStr.append(ConfigRead.NL);
				}
			}
			switch (strings[2]) {
				case "NUMBER" : 
				case "NUMERIC" : 
				case "DECIMAL" : 
					if(strings[4] == null || "0".equals(strings[4])) {
						fieldType = "Long";
					} else {
//						if(Integer.parseInt(strings[3]) >= 9) {
//							fieldType = "BigDecimal";
//						} else {
//							fieldType = "Double";
//						}
						fieldType = "BigDecimal";
					}
					break;
				case "LONG" : 
				case "RAW" : 
				case "LONGRAW" : 
				case "BLOB" : 
				case "CLOB" : 
				case "NCLOB" : 
					fieldType = "byte[]";
					break;
				case "INTEGER" : fieldType = "Long"; break;
				case "FLOAT" : fieldType = "Float"; break;
				case "DATE" : fieldType = "Date"; break;
				case "TIMESTAMP" : fieldType = "Timestamp"; break;
//				case "CHAR" : 
//				case "NCHAR" : 
//				case "VARCHAR" : 
//				case "VARCHAR2" : 
//				case "NVARCHAR" : 
//				case "NVARCHAR2" : 
//					fieldType = "String";
//				break;
			}
			sbStr.append(String.format(ConfigRead.FORMAT_JAVA_FIELD, fieldType, strings[0], strings[1], string0, strings[2], strings[5] == null ? string3 : strings[5]+"."+strings[4]));
			sbStr.append(ConfigRead.NL);
		}
		if(ConfigRead.NOW_DB.equals(ConfigRead.MYSQL)) {
			if(ConfigRead.ANN_NOTNULL) {
				List<String> list = MysqlConnection.MAP_COLUMN_TYPE.get(ConfigRead.$NOT_NULL);
				if(list.contains(strings[2])) {
//					sbStr.append("@"+ConfigRead.NOT_NULL_VALUE+"(message=\"参数["+ strings[0]+"]不能为空\")");
					sbStr.append("@");
					sbStr.append(ConfigRead.NOT_NULL_VALUE);
					if(ConfigRead.MESSAGE_NOTNULL) {
						sbStr.append("(message=\""+ String.format(ConfigRead.MESSAGE_NOTNULL_VALUE, strings[0]) +"\")");
					}
					sbStr.append(ConfigRead.NL);
				}
			}
			if(ConfigRead.ANN_LENGTH && checkNumberLength(strings[3])) {
				List<String> maxs = MysqlConnection.MAP_COLUMN_TYPE.get(ConfigRead.$MAX);
				if(maxs.contains(strings[2])) {
					sbStr.append("@Max("+getLengthInt(strings[3])+")");
					sbStr.append(ConfigRead.NL);
				}
				List<String> lengths = MysqlConnection.MAP_COLUMN_TYPE.get(ConfigRead.$LENGTH);
				if(lengths.contains(strings[2])){
					if(ConfigRead.ANN_LENGTH_2 && checkNumberLength(strings[3])) {
						strings[3] = String.valueOf(Long.parseLong(strings[3]) / 2);
					}
//					sbStr.append("@Length(message=\"参数["+strings[0]+"]长度不能超过"+strings[3]+"\", max = "+strings[3]+")");
					sbStr.append("@Length");
					if(ConfigRead.MESSAGE_LENGTH) {
						sbStr.append("(message=\""+ String.format(ConfigRead.MESSAGE_LENGTH_VALUE, strings[0], strings[3]) +"\", max = "+strings[3]+")");
					} else {
						sbStr.append("(max = "+strings[3]+")");
					}
					sbStr.append(ConfigRead.NL);
				}
			}
			if(ConfigRead.ANN_DATE) {
				List<String> list = MysqlConnection.MAP_COLUMN_TYPE.get(ConfigRead.$DATE);
				if(list.contains(strings[2])) {
					sbStr.append("@DateTimeFormat(pattern = \""+ConfigRead.ANN_DATE_FORMAT+"\")");
					sbStr.append(ConfigRead.NL);
				}
			}
			switch (strings[2]) {
				case "tinyint" :
				case "smallint" :
				case "mediumint" :
					fieldType = "Integer"; break;
				case "int" :
				case "integer" :
				case "bigint" :
					fieldType = "Long"; break;
				case "time" :
					fieldType = "Time"; break;
				case "double" :
//				case "real" :
				case "numeric" :
//					fieldType = "Double"; break;
				case "decimal" :
					fieldType = "BigDecimal"; break;
				case "float" :
					fieldType = "Float"; break;
				case "date" :
				case "year" :
					fieldType = "Date"; break;
				case "datetime" :
				case "timestamp" :
					fieldType = "Timestamp"; break;
				case "bit" :
				case "blob" ://65K
				case "mediumblob" ://16M
				case "longblob" ://4G
				case "binary" :
				case "varbinary" :
					fieldType = "byte[]"; break;
//				case "set" :
//				case "enum" :
//				case "char" :
//				case "varchar" :
//				case "tinytext" :
//				case "text" :
//				case "mediumtext" ://16M
//				case "longtext" :
//					fieldType = "String"; break;
			}
			sbStr.append(String.format(ConfigRead.FORMAT_JAVA_FIELD, fieldType, strings[0], strings[1], string0, strings[2], string3));
			sbStr.append(ConfigRead.NL);
		}
		return sbStr;
	}
	
}
